home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / N-P / NIFTY / myCShell / window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-17  |  11.1 KB  |  457 lines  |  [TEXT/KAHL]

  1. /*********************************************************
  2.  "window.c"
  3.  
  4.  by John A. Love, III [ Washington Apple Pi Users' Group]
  5.  
  6.  using Symantec's "THINK C", v 5.00
  7.  *********************************************************/
  8.  
  9.  
  10. #include <string.h>
  11. #include <Palette.h>
  12.  
  13. #include "protos"
  14.  
  15. #include "globals.h"
  16. #include "extern.h"
  17.  
  18. #include "floatingWindow.h"
  19.  
  20.  
  21. // Local Prototypes:
  22. void    CalcWindowFrame (WindowPtr window, Rect *r);
  23. void    CloseBehind (WindowPtr window);
  24.  
  25.  
  26.     short                windType;
  27.     Boolean                windHasGrowIcon, currAppWind = true;
  28.     extern DialogPtr    helpPtr;
  29.  
  30.  
  31.  
  32.  
  33. Boolean    isActive (WindowPtr window)    {
  34.  
  35.  
  36.     return (gInForeGround && (window != nil) && ((WindowPeek)window)->hilited);
  37.     
  38. }    /* isActive */
  39.  
  40.  
  41.  
  42. void DoWindow (void)    {
  43.  
  44.     static short        windowCount, newCount;
  45.     short                windowLoc;
  46.  
  47.     
  48. }    /* DoWindow */
  49.  
  50.  
  51.  
  52. short GetWindowType (WindowPtr window)    {
  53.  
  54.         short        RomMapInsertLoc    = 0x0B9E;
  55.      /* short        mapTrue            = -1; */
  56.  
  57.         short        varCode, WDEFRsrcID, wType;
  58.         Handle        WDEFHandle;
  59.         ResType        WDEFType;
  60.         Str255        WDEFName;
  61.  
  62.  
  63.     varCode = GetWVariant(window);
  64.  
  65.  /* Now, what about rDocProc types since their Variation
  66.     Codes duplicate those of some standard types such as
  67.     documentProc & dBoxProc.  I could call:
  68.  
  69.     regionSize = (**(((WindowPeek)window)->strucRgn)).rgnSize;
  70.  
  71.     If regionSize = 10, then rgnBBox is rectangular; so
  72.     if <> 10, we've got an rDocProc.  HOWEVER,  if the
  73.     window is invisible because I've not yet called
  74.     _ShowWindow, rgnBBox is empty and regionSize STILL
  75.     equals 10.  The solution is simple ... call
  76.     GetWindowType when the window is being activated.
  77.     Better yet ... the solution presented below, thanks
  78.     to MacDTS, avoids this workaround.  In addition,
  79.     MacDTS' solution avoids the pitfalls of "Murphy"
  80.     inventing a totally new window type with a regionSize
  81.     that dupes that of rDocProc.                            */
  82.     
  83.  /*
  84.     Simple looking, ain't it !*?*!
  85.     WDEFHandle = (Handle)QuickStrip((longPtr)(*((WindowPeek)window)).windowDefProc);
  86.  */
  87.  
  88.     WDEFHandle = ((WindowPeek)window)->windowDefProc;        // Even neater !!
  89.     WDEFHandle = (Handle)QuickStrip((longPtr)WDEFHandle);
  90.     ;
  91.     LoadResource(WDEFHandle);                /* May have been purged ... */
  92.     *((wordPtr)RomMapInsertLoc) = mapTrue;    /* Thanks, Ben Cranston !! */
  93.     GetResInfo(WDEFHandle, &WDEFRsrcID, &WDEFType, WDEFName);
  94.  
  95.     wType = 16 * WDEFRsrcID + varCode;        // = ProcID.
  96.  
  97.     return (wType);
  98.  
  99. }    /* GetWindowType */
  100.  
  101.  
  102.  
  103. Boolean        hasGrowIcon (WindowPtr window)        {
  104.  
  105.         short        wType;
  106.         
  107.  
  108.     wType = GetWindowType(window);
  109.     if ( (wType == documentProc) || (wType == zoomDocProc) )
  110.         return (true);
  111.     else
  112.         return ( (ScrollHoriz(window) != nil) || (ScrollVert(window) != nil) );
  113.     
  114. }    /* hasGrowIcon */
  115.  
  116.  
  117.  
  118. /* ---------------------------------------------------------------
  119.    Make a separate PROC so we can zoom independently of _TrackBox,
  120.    for example, in response to a Menu selection or a keypress:
  121.    --------------------------------------------------------------- */
  122.  
  123. void    DoZoom (WindowPtr window, short zoomDir)    {
  124. /* Reference: Tech Note #79 */
  125.  
  126.         typedef    WStateData        *WStateDataPtr, **WStateDataHdl;
  127.  
  128.         GrafPtr        oldPort;
  129.         WindowPeek    wPeek;
  130.         Rect        r, windRect, zoomRect;
  131.         GDHandle    dominantGDevice;
  132.         short        bias;
  133.  
  134.  
  135.     wPeek = (WindowPeek)window;            /* Looks less messy below !!! */
  136.  
  137.     if ( (window == nil) || (wPeek->windowKind != userKind) )    return;
  138.     ;
  139.     GetPort(&oldPort);
  140.     SetPort(window);
  141.  
  142.     /* If there is the possibility of multiple gDevices, then we must check them
  143.        to make sure we are zooming onto the right display device when zooming out. */
  144.     if ((zoomDir == inZoomOut) && gMac2)    {
  145.  
  146.         /* Window's portRect must be converted to global coordinates: */
  147.         windRect = window->portRect;
  148.         LocalGlobal(&windRect);
  149.         
  150.         /* Must calculate height of window's title bar */
  151.         bias = windRect.top - 1 - (**(wPeek->strucRgn)).rgnBBox.top;
  152.         windRect.top = windRect.top - bias;
  153.  
  154.         dominantGDevice = GetMaxAreaDevice(&windRect);
  155.  
  156.         /* We must create a zoom rectangle manually in this case &
  157.            account for menu bar height as well, if on main device. */
  158.         if (dominantGDevice == GetMainDevice())    bias = bias + gMBarHt;
  159.         
  160.         r = (**dominantGDevice).gdRect;
  161.         SetRect(&zoomRect,
  162.                 r.left + 3,
  163.                 r.top + bias + 3,
  164.                 r.right - 3,
  165.                 r.bottom - 3);
  166.  
  167.         /* Set up the WStateData record for this window. */
  168.         (*(WStateDataHandle)(wPeek->dataHandle))->stdState = zoomRect;
  169.  
  170.     }    /* inZoomOut & color Quickdraw */
  171.  
  172.     EraseRect(&(window->portRect));
  173.     ShowHide(window, false);
  174.     ZoomWindow(window, zoomDir, false);      /* NO Activate Event !! */
  175.     InvalRect(&(window->portRect));
  176.     ScrollResize(window);
  177.     ShowHide(window, true);
  178.  
  179.     switch(zoomDir)    {
  180.     
  181.         case inZoomOut:    PlaySound("ZoomOut"); break;
  182.  
  183.         case inZoomIn: PlaySound("ZoomIn"); break;
  184.  
  185.     }    /* switch */
  186.  
  187.     SetPort(oldPort);
  188.  
  189. }    /* DoZoom */
  190.  
  191.  
  192.  
  193. WindowPtr    SelectNextWindow (void)    {
  194.  
  195.         WindowPtr    fWind;
  196.         WindowPeek    wind2, wind3;
  197.         
  198.         
  199.     fWind = FrontWindow();
  200.     wind2 = ((WindowPeek)fWind)->nextWindow;
  201.     wind3 = wind2->nextWindow;
  202.     /* System 6.xx w/DA in application heap: */
  203.     while ((wind2 != nil) && (wind2->windowKind != userKind))    {
  204.         wind2 = wind2->nextWindow;
  205.     }    /* while */
  206.     ;
  207.     if (wind2 != nil)    {
  208.         SelectWindow((WindowPtr)wind2);
  209.         /* What used to be the front window, send to back
  210.            so we rotate windows in a circular fashion      */
  211.         if (wind3 != nil)    SendBehind(fWind, nil);
  212.     }    /* outer if */
  213.     
  214.     return ((WindowPtr)wind2);
  215.         
  216. }    /* SelectNextWindow */
  217.  
  218.  
  219.  
  220. /* ---------------------------------------------------------
  221. ** CanNOT use the "structRgn" field of the window since this
  222. ** region handle will be NIL if the window is NOT visible.
  223. ** --------------------------------------------------------- */
  224.  
  225. void    CalcWindowFrame (WindowPtr window, Rect *r)    {
  226.  
  227.  
  228.     windType = GetWindowType(window) % 16;
  229.  
  230.     *r = window->portRect;
  231.     InsetRect(r, -frame, -frame);
  232.     if ((windType == 0) || (windType > 3))
  233.         r->top = r->top - title;            /* Window has a title bar. */
  234.     if (
  235.         (windType == documentProc) || (windType == altDBoxProc) ||
  236.         (windType == noGrowDocProc) || (windType == zoomDocProc)
  237.        )
  238.     {
  239.         r->bottom = r->bottom + shadow;
  240.         r->right = r->right + shadow;
  241.     }    /* Window has a shadow frame. */
  242.  
  243. }    /* CalcWindowFrame */
  244.  
  245.  
  246.  
  247. void    CenterWindow (WindowPtr window)    {
  248. /* Centers window on MAIN screen. */
  249.  
  250.         Rect    screen, wFrameRect;
  251.         short    temp;
  252.         Point    Pt;
  253.  
  254.  
  255.     CalcWindowFrame(window, &wFrameRect);        // Calculates windType.
  256.  
  257.     if (gMac2)        screen = (**GetMainDevice()).gdRect;    // = global.
  258.     else            screen = screenBits.bounds;                // Here, local = global.
  259.     screen.top = screen.top + gMBarHt;                        // Below MenuBar.
  260.  
  261.     temp = screen.bottom - screen.top;
  262.     /* screen height - window height: */
  263.     temp = temp - (wFrameRect.bottom - wFrameRect.top);
  264.     temp = temp / 2;
  265.     temp = temp + frame;
  266.     if ((windType == 0) || (windType > 3))
  267.         temp = temp + title;                    // Window has a title bar.
  268.     Pt.v = screen.top + temp;
  269.     /* ----- */
  270.     temp = screen.right - screen.left;
  271.     /* screen width - window width: */
  272.     temp = temp - (wFrameRect.right - wFrameRect.left);
  273.     Pt.h = screen.left + temp / 2 + frame;
  274.  
  275.     MoveWindow(window, Pt.h, Pt.v, TRUE);
  276.  
  277. }    /* CenterWindow */
  278.  
  279.  
  280.  
  281. /* -----------------------------------------------------
  282. ** Before showing the window, position it on the screen.
  283. ** ----------------------------------------------------- */
  284.  
  285. void    DisplayWindow (WindowPtr window, Boolean activate)        {
  286.  
  287.         WindowPtr        frontWindow;
  288.         Boolean            extraField;
  289.         Str255            wTitle;
  290.         short            index, windType, rType;
  291.         Handle            rHdl;
  292.  
  293.  
  294.     frontWindow = FrontWindow();        /* anyKind */
  295.     if (!frontWindow)        {
  296.  
  297.         if (!gSys7)        extraField = false;
  298.         else
  299.         {
  300.             extraField = false;            // Assume NOT there !!
  301.             
  302.             windType = GetWindowType(window);
  303.             GetWTitle(window, wTitle);
  304.             ;
  305.             for (index = 1; index <= Count1Resources('WIND'); index++)
  306.             {
  307.                 rHdl = Get1IndResource('WIND', index);
  308.                 if (rHdl == nil)    continue;
  309.                 asm    {
  310.                     move.l    rHdl, a0
  311.                     move.l    (a0), a0
  312.                     move.w    8(a0), rType
  313.                 }
  314.                 // Compare window types:
  315.                 if (windType == rType)    {
  316.                     /*
  317.                         oldType        |                newType
  318.                         -------        |                -------
  319.                       18 + 1 + len    |    a) odd  length:    18 + 1 + len + 2
  320.                                     |    b) even length:    18 + 1 + len + fill byte + 2
  321.                     */
  322.                     if ( GetHandleSize(rHdl) > 18 + 1 + wTitle[0] + 1 )
  323.                         extraField = true;
  324.                     break;
  325.                 }
  326.             }    /* end for-loop */
  327.             
  328.         }    // System 7.
  329.     
  330.         if (!extraField)    CenterWindow(window);
  331.      /* else do what the extra field stipulates. */
  332.      
  333.     }    /* NO front window */
  334.     
  335.     else    {
  336.  
  337.             Rect    screenRect, frontWindRect, myWindRect;
  338.             Point    whereTL, whereBR;
  339.             short    myWindWidth, myWindHeight;
  340.             
  341.     
  342.         if ( !((WindowPeek)window)->visible    /* brand new      */    ||
  343.              EmptyRgn(window->visRgn)        /* totally hidden */ )    {
  344.         
  345.             if (gMac2)        screenRect = (**GetMainDevice()).gdRect;
  346.             else            screenRect = screenBits.bounds;
  347.             // Get below MenuBar and accomodate for a possible window Title Bar:
  348.             screenRect.top = screenRect.top + gMBarHt + 20;
  349.  
  350.          // GetPort(¤tWindow /* = passed window */);
  351.             SetPort(frontWindow);
  352.             ;
  353.             frontWindRect = frontWindow->portRect;
  354.             LocalGlobal(&frontWindRect);
  355.             ;
  356.             SetPort(window);
  357.         
  358.             /* Try to get WHOLE window to fit on screen &
  359.             ** NOT obscure any of the existing front window: */
  360.             
  361.             myWindRect = window->portRect;
  362.             myWindWidth = myWindRect.right  - myWindRect.left;
  363.             myWindHeight = myWindRect.bottom - myWindRect.top;
  364.             whereBR = botRight(frontWindRect);
  365.             // PortRect starts BELOW possible Title Bar:
  366.             SetPt(&whereTL, whereBR.h + 5, whereBR.v + 25);
  367.             SetPt(&whereBR, whereTL.h + myWindWidth, whereTL.v + myWindHeight);
  368.             if ( !PtInRect(whereBR, &screenRect) )    {
  369.                 whereTL = topLeft(frontWindRect);
  370.                 SetPt(&whereBR, whereTL.h - 5, whereTL.v - 5);
  371.                 SetPt(&whereTL, whereBR.h - myWindWidth, whereBR.v - myWindHeight);
  372.                 if ( !PtInRect(whereTL, &screenRect) )    whereTL = topLeft(screenRect);
  373.             }
  374.             MoveWindow (window, whereTL.h, whereTL.v, activate);
  375.         
  376.         }    /* end: moving the window */
  377.                         
  378.     }    /* somein in front */
  379.     
  380.     if (activate)        ShowWindow(window);
  381.     else                ShowHide(window, TRUE);
  382.     ;
  383.     ScrollResize(window);
  384.  
  385. }    /* DisplayWindow */
  386.  
  387.  
  388.  
  389. void    CloseOurWindow (WindowPtr window)    {
  390.  
  391.         PaletteHandle        pal;
  392.         PicHandle            myPic;
  393.         TEHandle            textH;
  394.     
  395.     
  396.     if (window == nil)    return;
  397.  
  398.     if ( ((WindowPeek)window)->windowKind < 0)
  399.         CloseDeskAcc( ((WindowPeek)window)->windowKind );
  400.         
  401.     else if (window == helpPtr)        Kill_Help_Window();
  402.     else    {
  403.     
  404.         if (gMac2)    {
  405.             pal = GetPalette(window);
  406.             if (pal != nil)        DisposePalette(pal);
  407.         }    /* a Mac2 */
  408.  
  409.         myPic = GetWindowPic(window);
  410.         if (myPic != nil)    {
  411.             HUnlock(myPic);
  412.             ReleaseResource(myPic);
  413.         }
  414.  
  415.         textH = (TEHandle)GetWRefCon(window);
  416.         if (textH != nil)        TEDispose(textH);
  417.  
  418.         DisposeWindow(window);
  419.         
  420.     }    /* neither a DA nor our Help Window */
  421.  
  422. }    /* CloseOurWindow */
  423.  
  424.  
  425.  
  426. /* -----------------------------------------------------------
  427. ** DoCloseAll is called from within "DoQuit".  Note that we
  428. ** close windows from back to front by calling CloseBehind
  429. ** recursively.  In this manner, window updating is minimized.
  430. ** Reference: APDA's "Programmer's Guide to MultiFinder" [B-5]
  431. ** ----------------------------------------------------------- */
  432.  
  433. void    DoCloseAll (void)    {
  434.  
  435.  
  436.     CloseBehind(FrontWindow());
  437.  
  438. }    /* DoCloseAll */
  439.  
  440.  
  441. void    CloseBehind (WindowPtr window)    {
  442.  
  443.         WindowPeek        next;
  444.  
  445.  
  446.     if (window != nil)        {
  447.         next = ((WindowPeek)window)->nextWindow;
  448.         CloseBehind( (WindowPtr) (next) );
  449.         CloseOurWindow(window);
  450.     }
  451.  
  452. }    /* CloseBehind */
  453.  
  454.  
  455.  
  456. /*    { end file "window.c" }  */
  457.